package org.budo.support.lang.comparator;

import java.util.Comparator;

import org.budo.support.lang.util.ReflectUtil;

/**
 * @author lmw
 */
public class FieldComparator implements Comparator<Object> {
    private String fieldName;

    public FieldComparator(String fieldName) {
        this.fieldName = fieldName;
    }

    @Override
    public int compare(Object o1, Object o2) {
        Integer compare = this.compareIfNullOrEquals(o1, o2);
        if (null != compare) {
            return compare;
        }

        Comparable<?> c1 = (Comparable<?>) this.getFieldValue(o1, this.fieldName);
        Comparable<?> c2 = (Comparable<?>) this.getFieldValue(o2, this.fieldName);

        return this.compareTo(c1, c2);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    private Integer compareTo(Comparable c1, Comparable c2) {
        Integer compare = this.compareIfNullOrEquals(c1, c2);
        if (null != compare) {
            return compare;
        }

        return c1.compareTo(c2);
    }

    private Integer compareIfNullOrEquals(Object c1, Object c2) {
        if (null == c1 && null == c2) {
            return 0;
        }

        if (null == c1) {
            return -1;
        }

        if (null == c2) {
            return 1;
        }

        if (c1.equals(c2)) {
            return 0;
        }

        return null;
    }

    protected Object getFieldValue(Object target, String fieldName) {
        return ReflectUtil.getFieldValue_0(target, fieldName);
    }
}